package com.itmuch.contentcenter.controller;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.itmuch.contentcenter.dao.content.ShareMapper;
import com.itmuch.contentcenter.domain.dto.user.UserDTO;
import com.itmuch.contentcenter.domain.entity.content.Share;
import com.itmuch.contentcenter.feignclient.TestBaiduFeignClient;
import com.itmuch.contentcenter.feignclient.UserCenterFeignClient;
import com.itmuch.contentcenter.rocketmq.MySource;
import com.itmuch.contentcenter.service.content.TestService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.http.*;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

@RestController
@Slf4j
@RefreshScope
public class Testcontroller {

    @Resource
    private Source source;

    @Resource
    private MySource mySource;

    @Resource
    private ShareMapper shareMapper;

    @Resource
    private DiscoveryClient discoveryClient;

    @Resource
    private UserCenterFeignClient userCenterFeignClient;

    @Resource
    private TestBaiduFeignClient testBaiduFeignClient;

    @Resource
    private TestService testService;

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("test")
    public List<Share> testInsert(){
    Share share = Share.builder()
            .author("asd")
            .auditStatus("qwe")
            .reason("asdasd")
            .createTime(new Date())
            .updateTime(new Date())
            .build();
    System.out.println(share.toString());
    shareMapper.insertSelective(share);
        System.out.println(share.toString());
        List<Share> shareList = shareMapper.selectAll();
    return shareList;
  }

    @GetMapping("test2")
    public List<ServiceInstance> setDiscoveryClient(){
        System.out.println(discoveryClient.getServices());
        return discoveryClient.getInstances("user-center");
    }

    @GetMapping("q")
    public UserDTO query(UserDTO userDTO){
        return userCenterFeignClient.query(userDTO);
    }

    @GetMapping("baidu")
    public String test(){
        return testBaiduFeignClient.index();
    }

    @GetMapping("test-a")
    public String testA(){
        return testService.common()+"A";
    }

    @GetMapping("test-b")
    public String testB(){
        return testService.common()+"B";
    }

    @GetMapping("test-hot")
    @SentinelResource("hot")
    public String testHot(
           @RequestParam(required = false) String a,
           @RequestParam(required = false) String b
    ){
        return a+"   "+b;
    }

    @GetMapping("test-sentinel-api")
    public String testSentinelApi(
            @RequestParam(required = false) String a){
        Entry entry = null;
        String resource = "test-sentinel-api";
        ContextUtil.enter(resource,"test-wfw");
        try {
            entry = SphU.entry(resource);

            if (StringUtils.isBlank(a)){
                throw new IllegalArgumentException();
            }
            return  a;
        }catch (BlockException e){
            log.warn("限流或者降级了",e);
            return "限流或者降级了";
        }catch (IllegalArgumentException e){
            Tracer.trace(e);
            return "报异常";
        }
        finally {
            if (entry!=null){
                entry.exit();
            }
            ContextUtil.exit();
        }
    }

    @GetMapping("resource-sentinel-api")
    @SentinelResource(value = "resource-sentinel-api"
    ,blockHandler = "block"
    ,fallback = "fallback"
    )
    public String testSentinelApi1(
            @RequestParam(required = false) String a){
            if (StringUtils.isBlank(a)){
                throw new IllegalArgumentException();
            }
            return a;
    }

    public String block(
            @RequestParam(required = false) String a,BlockException e){
        log.warn("降级了");
        return "降级了={}"+a+e;
    }

    public String fallback(
            @RequestParam(required = false) String a){
        log.warn("降级了fallback");
        return "降级了 fallback"+a;
    }

    @GetMapping("/test-stream")
    public String testStream(){
        this.source.output()
                .send(MessageBuilder.withPayload("消息体，你好").build());
        return "success";
    }

    @GetMapping("/test-stream-2")
    public String testStream2(){
        this.mySource.output()
                .send(MessageBuilder.withPayload("mySource,hello").build());
        return "success";
    }

    @GetMapping("/tokenRelay/{userId}")
    public ResponseEntity<UserDTO> tokenRelay(@PathVariable("userId") Integer userId, HttpServletRequest httpServletRequest){
//        String token = httpServletRequest.getHeader("Token-X");
//        HttpHeaders httpHeaders = new HttpHeaders();
//        httpHeaders.add("Token-X",token);
//        return this.restTemplate.exchange(
//                "http://user-center/users/{userId}",
//                HttpMethod.GET,
//                new HttpEntity<UserDTO>(httpHeaders),
//                UserDTO.class,userId
//        );
        System.out.println("httpServletRequest.getAttribute(\"role\")"+httpServletRequest.getAttribute("role"));
                String targetUri = "http://user-center/users/{userId}";
        return new ResponseEntity<UserDTO>(this.restTemplate.getForObject(
                targetUri,
                UserDTO.class,userId
        ),HttpStatus.ACCEPTED);

    }

    @Value("${your.configuration}")
    private String testConfig;

    @RequestMapping("/config/info")
    public String testConfig(){
    return testConfig;
    }

    @RequestMapping("/test-node-service")
    public String testNodeService(){
        return this.restTemplate.getForObject("http://wii-node-service",String.class);
    }

}
